package com.jiangyg.mall.authz.support.authentication.admin;

import com.jiangyg.mall.authz.constant.SecurityConstant;
import com.jiangyg.mall.authz.UserInfo;
import com.jiangyg.mall.authz.service.AdminAuthenticationService;
import com.jiangyg.mall.authz.support.TokenUtils;
import com.jiangyg.mall.core.support.restful.Result;
import com.jiangyg.mall.core.utils.Logger;
import com.jiangyg.mall.core.utils.WebUtils;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 类描述：退出登录处理器
 *
 * @author jiangyg
 * @version 4.0
 * @date 2021-10-09
 */
@Slf4j
public class AdminLogoutHandler implements LogoutHandler {

    /**
     * 后台管理权限认证相关实现
     */
    private final AdminAuthenticationService adminAuthenticationService;

    public AdminLogoutHandler(AdminAuthenticationService adminAuthenticationService) {
        this.adminAuthenticationService = adminAuthenticationService;
    }

    /**
     * 功能描述：根据请求中的token信息，清除安全认证的缓存
     *
     * @param request        请求
     * @param response       响应
     * @param authentication 认证
     */
    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        final String token = request.getHeader(SecurityConstant.tokenName());
        if (StringUtils.isNotBlank(token)) {
            try {
                // 1. 解析token令牌信息
                final UserInfo user = TokenUtils.parse(token, SecurityConstant.securityBase64(), UserInfo.class);
                // 2. 执行退出登录操作
                adminAuthenticationService.logout(user);
                Logger.info(log, () -> String.format("用户[%s]退出登录成功", user.getUsername()));
            } catch (ExpiredJwtException ex) {
                // token 过期不处理
            } catch (Exception ex) {
                Logger.error(log, () -> "退出登录请求发生未知异常：", ex);
            }
        }
        WebUtils.out(response, Result.ok());
    }

}
